package com.starsoft.frame.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;


public class DateUtil {
	
	public static Timestamp getTimestamp(){
		Date d=new Date();
		Timestamp ts=new Timestamp(d.getTime());
		return ts;
	}
	
	public static Timestamp toStamp(Date date){
		Timestamp ts=new Timestamp(date.getTime());
		return ts;
	}
	
	public static Date parseDate(String str) {
		if(StringUtil.isEmpty(str))return null;
		Date re=null;
		try {
			Long time=Long.parseLong(str);
			re=new Date(time);
		} catch (Exception e) {
			re=null;
		}
		return re;
	}

	public static LocalDate toLocalDate(Date date){
		return toZoned(date).toLocalDate();
	}
	
	public static ZonedDateTime toZoned(Date date){
		long millionSeconds = date.getTime();
		Instant instant = Instant.ofEpochMilli(millionSeconds);
		return instant.atZone(ZoneId.systemDefault());
	}
	
	public static String toString(Date date) {
		return DateUtil.toString(date, "yyyy-MM-dd");
	}
	
	public static String toString(Date date, String format){
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}
	
	public static Date toDate(String date, String format){
		if("timestamp".contentEquals(format)) {
			return new Date(Long.parseLong(date));
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			return dateFormat.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static Date toDate(ZonedDateTime zonedDateTime){
		return Date.from(zonedDateTime.toInstant());
	}
	
	public static Date toDate(int year, int month, int day){
		ZonedDateTime zonedDateTime = LocalDate.of(year,month,day).atStartOfDay().atZone(ZoneId.systemDefault());
		return toDate(zonedDateTime);
	}
	
	/**
	 * 去掉date的时间部分
	 */
	public static Date floorTime(Date date){
		ZonedDateTime time = toZoned(date);
		ZonedDateTime floorTime = time.withHour(0).withMinute(0).withSecond(0).withNano(0);
		return Date.from(floorTime.toInstant());
	}
	
	/**
	 * 将时间部分设置为一天中最大
	 */
	public static Date ceilTime(Date date){
		ZonedDateTime time = toZoned(date);
		ZonedDateTime floorTime = time.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
		return Date.from(floorTime.toInstant());
	}
	
	public static double getYears(Date beginDate, Date endDate) {
		ZonedDateTime beginDate2 = toZoned(beginDate);
		ZonedDateTime endDate2 = toZoned(endDate);
		double years = endDate2.getYear() - beginDate2.getYear();
		Duration duration = Duration.between(beginDate2.withYear(endDate2.getYear()), endDate2);
		years += (duration.toDays() / 365.0);
		return years;
	}
	
	public static long getDays(Date beginDate, Date endDate){
		ZonedDateTime beginDate2 = toZoned(beginDate);
		ZonedDateTime endDate2 = toZoned(endDate);
		Duration duration = Duration.between(beginDate2, endDate2);
		return duration.toDays();
	}
	
	public static Date getLast(Date date){
		return Date.from(toZoned(date).plusDays(-1).toInstant());
	}
	
	public static Date getNext(Date date){
		return Date.from(toZoned(date).plusDays(1).toInstant());
	}
	
	public static Date bumpDate(Date date, int year, int month, int day){
		ZonedDateTime date2 = toZoned(date);
		date2 = date2.plusYears(year).plusMonths(month).plusDays(day);
		return Date.from(date2.toInstant());
	}
	
	public static boolean isToday(Date date){
		LocalDate date2 = toLocalDate(date);
		LocalDate today = LocalDate.now();
		return today.equals(date2);
	}
	
	public static boolean isWeekend(Date date){
		return isWeekend(toZoned(date));
	}
	
	public static boolean isWeekend(ZonedDateTime dateTime){
		DayOfWeek dayOfWeek = dateTime.getDayOfWeek();
		if(dayOfWeek==DayOfWeek.SUNDAY||dayOfWeek==DayOfWeek.SATURDAY){
			return true;
		}
		return false;
	}
	
	public static boolean isSameDay(Date date1, Date date2) {
		if (date1 == null && date2 == null) {
			return true;
		} else if (date1 == null || date2 == null) {
			return false;
		} else {
			LocalDate localDate1 = toLocalDate(date1);
			LocalDate localDate2 = toLocalDate(date2);
			if (localDate1.equals(localDate2)) {
				return true;
			}
		}
		return false;
	}

}
